#include "Character.hh"
#include <iostream>

Character::Character(const std::string& n, const std::string& desc,
    unsigned health, unsigned attack, unsigned defense)
    : name(n), description(desc),
    baseHealth(health), currentHealth(health),
    baseAttack(attack), baseDefense(defense) {
}

Character::~Character() {
    for (auto item : inventory) {
        delete item;
    }
    inventory.clear();  
}
std::vector<Item*> Character::possibleLoot;
bool Character::isAlive() const {
    return currentHealth > 0;
}


void Character::initializeLootTable() {
    possibleLoot.push_back(new Item("Magic Sword", "An enchanted longsword", 0, 5, 0));
    possibleLoot.push_back(new Item("Jewel Shield", "A shield made of gemstones that provides a strong defense", 0, 0, 5));
    possibleLoot.push_back(new Item("Lucky rings", "A magic ring that improves your abilities in an all-round way", 10, 2, 2));
    possibleLoot.push_back(new Item("Blade of Mana", "A short knife full of magical powers", 0, 8, 0));
    possibleLoot.push_back(new Item("Diamond armor", "A piece of diamond-encrusted armor that provides extreme defense", 0, 0, 8));
    possibleLoot.push_back(new Item("The Staff of Life", "A staff full of life", 15, 3, 3));
}

Item* Character::generateRandomItem() {
    if (possibleLoot.empty()) {
        initializeLootTable();
    }
    int index = rand() % possibleLoot.size();
    Item* original = possibleLoot[index];
    return new Item(original->name, original->description,
        original->healthBonus, original->attackBonus, original->defenseBonus);
}


bool Character::takeDamage(unsigned damage) {
    // Calculate the damage after defense
    unsigned actualDamage = (damage > getDefense()) ? (damage - getDefense()) : 0;

    if (actualDamage > 0) {
        if (actualDamage >= currentHealth) {
            currentHealth = 0;
        }
        else {
            currentHealth -= actualDamage;
        }
    }

    return !isAlive(); // Returns whether it is dead or not
}

bool Character::attack(ICharacter& target) {
    return target.takeDamage(getAttack());
}

std::string Character::getName() const {
    return name;
}

std::string Character::getDescription() const {
    return description;
}

unsigned Character::getHealth() const {
    return currentHealth;
}

unsigned Character::getAttack() const {
    unsigned totalAttack = baseAttack;
    for (const auto& item : inventory) {
        totalAttack += item->attackBonus;
    }
    return totalAttack;
}

unsigned Character::getDefense() const {
    unsigned totalDefense = baseDefense;
    for (const auto& item : inventory) {
        totalDefense += item->defenseBonus;
    }
    return totalDefense;
}

std::string Character::toString() const {
    return name + " (Health: " + std::to_string(currentHealth) + ")";
}

void Character::addToInventory(Item* item) {
    inventory.push_back(item);

    // Increases health
    if (item->healthBonus > 0) {
        baseHealth += item->healthBonus;
        currentHealth += item->healthBonus;
    }
}

void Character::displayInventory() const {
    if (inventory.empty()) {
        std::cout << "The backpack is empty" << std::endl;
        return;
    }

    std::cout << "Backpack items:" << std::endl;
    for (size_t i = 0; i < inventory.size(); ++i) {
        std::cout << i + 1 << ". " << inventory[i]->toString() << std::endl;
    }
}

void Character::display() const {
    std::cout << toString() << std::endl;
}




//角色管理系统：
//1.确定角色属性:角色名称和描述，确定了基础生命值和当前生命值，基础攻击力和防御力以及角色所持物品。
//2.关键功能实现：初始化角色基础属性：当前生命值为满。    实现了战斗系统：计算实际伤害，利用布尔值确定角色是否死亡。    
//物品管理：初始化6种预设物品，包含生命、攻击、防御加成。  属性计算：动态计算总属性（基础值 + 物品加成）。     辅助功能：判断角色是否存活和显示背包内容

//Role Management System:
//1. Determine the character attributes : the character name and description, determine the base health and current health, the base attack and defense, and the items held by the character.
//2. Key function implementation : Initialize the basic attributes of the character : the current health value is full.   
// A combat system is implemented : the actual damage is calculated, and the Boolean value is used to determine whether the character dies or not.
//Item Management : Initialize 6 preset items, including health, attack, and defense bonuses.
// Attribute Calculation : Dynamically calculates the total attribute(base value item bonus).
// Accessibility : Determines if a character is alive and displays backpack contents
